import initShader from '../utils/initShader-square03'

const canvasElement = document.createElement('canvas');

canvasElement.width = 600;
canvasElement.height = 600;
canvasElement.style.backgroundColor = '#000';
document.body.appendChild(canvasElement);

const gl = canvasElement.getContext('webgl'); //3d 上下文对象
const program = initShader(gl)

// 一个面可看成两个三角形

const vertices = new Float32Array([
  // 前
  -0.5, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0,  //第一个点的x,y坐标1     0
  -0.5, -0.5, 0.5, 1.0, 0.5, 1.0, 1.0,  //第二个点的x,y坐标2    1
  0.5, -0.5, 0.5, 1.0, 0.5, 1.0, 1.0,  //第三个点的x,y坐标3     2
  0.5, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0,  //第四个点的x,y坐标4      3

  // 后
  -0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 1.0,  //第一个点的x,y坐标5    4
  -0.5, -0.5, -0.5, 1.0, 1.0, 0.5, 1.0,  //第二个点的x,y坐标6   5
  0.5, -0.5, -0.5, 1.0, 1.0, 0.5, 1.0,  //第三个点的x,y坐标7    6
  0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 1.0,  //第四个点的x,y坐标8     7

  // 左
  0.5, 0.5, 0.5, 1.0, 0.0, 1.0, 1.0,  //第四个点的x,y坐标4      8
  0.5, -0.5, 0.5, 1.0, 0.0, 1.0, 1.0,  //第三个点的x,y坐标3     9
  0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0,  //第三个点的x,y坐标7    10
  0.5, 0.5, -0.5, 1.0, 0.0, 1.0, 1.0,  //第四个点的x,y坐标8     11

  // 右
  -0.5, 0.5, 0.5, 1.0, 0.6, 0.0, 1.0,  //第一个点的x,y坐标1     12
  -0.5, -0.5, 0.5, 1.0, 0.6, 0.0, 1.0,  //第二个点的x,y坐标2    13
  -0.5, -0.5, -0.5, 1.0, 0.6, 0.0, 1.0,  //第二个点的x,y坐标6   14
  -0.5, 0.5, -0.5, 1.0, 0.6, 0.0, 1.0,  //第一个点的x,y坐标5    15

  // 上
  -0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 1.0,  //第一个点的x,y坐标1     16
  0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 1.0,  //第四个点的x,y坐标4      17
  0.5, 0.5, -0.5, 1.0, 0.5, 0.5, 1.0,  //第四个点的x,y坐标8     18
  -0.5, 0.5, -0.5, 1.0, 0.5, 0.5, 1.0,  //第一个点的x,y坐标5    19

  // 下
  0.5, -0.5, 0.5, 1.0, 0.0, 0.3, 1.0,  //第三个点的x,y坐标3     20
  0.5, -0.5, -0.5, 1.0, 0.0, 0.3, 1.0,  //第三个点的x,y坐标7    21
  -0.5, -0.5, -0.5, 1.0, 0.0, 0.3, 1.0,  //第二个点的x,y坐标6   22
  -0.5, -0.5, 0.5, 1.0, 0.0, 0.3, 1.0,  //第二个点的x,y坐标2    23
])

const buffer = gl.createBuffer(); // 创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // 绑定缓冲区
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // 填充缓冲区

const a_position_location = gl.getAttribLocation(program, 'a_position'); // 获取着色器中的attribute变量的地址
/**
 * 顶点属性的索引位置
 * 每个顶点属性的组件数量
 * 指定数组中每个组件的数据类型[gl.BYTE、gl.UNSIGNED_BYTE、gl.SHORT、gl.UNSIGNED_SHORT、gl.FLOAT]
 * 是否归一化
 * 指定连续顶点属性间的字节偏移量 【Float32Array.BYTES_PER_ELEMENT 一个元素的字节长】
 * 指定顶点属性数组中起始位置的字节偏移量
 */
gl.vertexAttribPointer(a_position_location, 3, gl.FLOAT, false, 7 * Float32Array.BYTES_PER_ELEMENT, 0); // 告诉 WebGL如何解析缓冲区中的数据
gl.enableVertexAttribArray(a_position_location); // 启用顶点属性数组

// const a_color_location = gl.getAttribLocation(program, 'a_color'); // 获取着色器中的attribute变量的地址
// gl.vertexAttribPointer(a_color_location, 4, gl.FLOAT, false, 7 * Float32Array.BYTES_PER_ELEMENT, 3 * Float32Array.BYTES_PER_ELEMENT); // 告诉 WebGL如何解析缓冲区中的数据
// gl.enableVertexAttribArray(a_color_location); // 启用顶点属性数组


// const a_angle_location = gl.getUniformLocation(program, 'a_angle'); // 获取着色器中的attribute变量的地址
// gl.uniform1fv(a_angle_location, [10]) //设置顶点属性数据


/**
 * WebGLRenderingContext.drawArrays()
 * WebGL API 中用于绘制图元（如点、线、三角形等）的方法。
 * 它从当前绑定的缓冲区中提取顶点数据，根据指定的绘制模式进行渲染。
 * 参数
 *  mode
 *    gl.POINTS: 绘制一系列点。​
 *    gl.LINES: 绘制一系列不连接的线段。
 *    ​gl.LINE_STRIP: 绘制一系列连接的线段。​
 *    gl.LINE_LOOP: 绘制一个闭合的线段环。
 *    gl.TRIANGLES: 绘制一系列不连接的三角形。
 *    ​gl.TRIANGLE_STRIP: 绘制一个三角形条带。
 *    ​gl.TRIANGLE_FAN: 绘制一个三角形扇形。
 * first: 从缓冲区数组中的哪个位置开始读取顶点数据
 * count: 要绘制的顶点数量
 */
// 1、
// gl.drawArrays(gl.LINE_LOOP, 0, 4); //绘制图元
// gl.drawArrays(gl.LINE_LOOP, 4, 4); //绘制图元
// gl.drawArrays(gl.LINE_LOOP, 8, 4); //绘制图元
// gl.drawArrays(gl.LINE_LOOP, 12, 4); //绘制图元

// 2、使用顶点索引的方式
const indices = new Uint16Array([
  0, 1, 2,
  0, 2, 3, 

  4, 5, 6,
  4, 6, 7,

  8, 9, 10,
  8, 10, 11,

  12, 13, 14,
  12, 14, 15,

  16, 17, 18,
  16, 18, 19,

  20, 21, 22,
  20, 22, 23,
])
const indexBuffer = gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)

// 绘制模式、索引数量、索引类型和偏移量等参数。
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0)

const faceColors = [
  [1.0, 1.0, 0.0, 1.0], //前
  [1.0, 1.0, 1.0, 1.0], //后

  [1.0, 0.8, 1.0, 0.0], //左
  [1.0, 0.8, 1.0, 0.0], //右

  [0.0, 1.0, 1.0, 0.0], //上
  [0.0, 1.0, 1.0, 0.0], //下
]
const ucolorLocation = gl.getUniformLocation(program, 'uColor')



const x_matrix = gl.getUniformLocation(program, 'x_matrix')
const y_matrix = gl.getUniformLocation(program, 'y_matrix')
let deg = 10


// window.requestAnimationFrame(callback) 短时间内执行callback，每秒60次

function render(){
  deg += 0.1

  const cos = Math.cos(deg * Math.PI / 180)
  const sin = Math.sin(deg * Math.PI / 180)

  gl.uniformMatrix4fv(x_matrix, false, new Float32Array([
    1, 0, 0, 0,
    0, cos, -sin, 0,
    0, sin, cos, 0,
    0, 0, 0, 1
  ]))
  gl.uniformMatrix4fv(y_matrix, false, new Float32Array([
    cos, 0, -sin, 0,
    0, 1, 0, 0,
    sin, 0, cos, 0,
    0, 0, 0, 1
  ]))

  for (let i = 0; i < faceColors.length; i++) {
    gl.uniform4fv(ucolorLocation, faceColors[i])
    // 绘制模式、索引数量、索引类型和偏移量等参数。
    gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 6 * i * Uint16Array.BYTES_PER_ELEMENT)
  } 
  gl.drawArrays(gl.LINE_LOOP, 0, 4); //绘制图元
  gl.drawArrays(gl.LINE_LOOP, 4, 4); //绘制图元
  gl.drawArrays(gl.LINE_LOOP, 8, 4); //绘制图元
  gl.drawArrays(gl.LINE_LOOP, 12, 4); //绘制图元

  window.requestAnimationFrame(render)
}

window.requestAnimationFrame(render)